package com.hunan.api.catv.service.biz.tencent_cloud.push;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.hunan.api.catv.common.CacheKey;
import com.hunan.api.catv.common.Constants;
import com.hunan.api.catv.common.ConstantsMsg;
import com.hunan.api.catv.entity.ServiceResult;
import com.hunan.api.catv.entity.enums.Channel;
import com.hunan.api.catv.entity.enums.ColumnEnum;
import com.hunan.api.catv.entity.enums.TpnsAudienceType;
import com.hunan.api.catv.entity.enums.TpnsContentType;
import com.hunan.api.catv.entity.vo.ActivityVo;
import com.hunan.api.catv.entity.vo.LiveVo;
import com.hunan.api.catv.entity.vo.MemberVo;
import com.hunan.api.catv.service.ResultService;
import com.hunan.api.catv.service.biz.activity.ActivityBiz;
import com.hunan.api.catv.service.biz.cache.CacheBiz;
import com.hunan.api.catv.service.biz.live.LiveBiz;
import com.hunan.api.catv.service.biz.member.MemberBiz;
import com.hunan.api.catv.service.impl.tencent_cloud.push.PushService;
import com.hunan.api.catv.utils.GsonUtils;
import com.hunan.api.catv.utils.RedisUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Set;

@Service
public class PushBiz extends ResultService {

    @Autowired
    PushService pushService;

    @Autowired
    CacheBiz cacheBiz;

    @Autowired
    ActivityBiz activityBiz;

    @Autowired
    LiveBiz liveBiz;

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    MemberBiz memberBiz;

    public ServiceResult push(Integer channel, JsonObject body) {
        log.info("[开始推送 channel:{} body:{}]", channel, body);
        JsonObject pushConf = GsonUtils.fromJson(cacheBiz.getSystemDict(Constants.tencent_cloud_push_conf), JsonObject.class);
        String url = pushConf.get("url").getAsString();
        String accessId = pushConf.get(Channel.getValue(channel.toString())).getAsJsonObject().get("accessId").getAsString();
        String secretKey = pushConf.get(Channel.getValue(channel.toString())).getAsJsonObject().get("secretKey").getAsString();
        String timeStamp = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")) + "";
        String original = timeStamp + accessId + body.toString();
        String sign = sign(original, secretKey);
        JsonObject result = pushService.push(url, accessId, timeStamp, sign, body);
        if (!ObjectUtils.isEmpty(result)) {
            Integer ret_code = result.get("ret_code").getAsInt();
            if (0 == ret_code) {
                return buildOK(result);
            }
        }
        return buildFail(ConstantsMsg.tpns_push_fail);
    }

    public void push(Integer audience_type, Integer channel, Integer contentType, String content) {
        String contentId = content;
        //推送目标：全部设备或按照用户
        JsonArray tokenList = new JsonArray();
        if (TpnsAudienceType.token_list.getCode().equals(audience_type)) {
            if (ColumnEnum.tv.getCode().equals(contentType)) {
                JsonObject schedule = GsonUtils.fromJson(content, JsonObject.class);
                contentId = schedule.get("scheduleId").getAsString();
            }
            String contentSubscribeKey = MessageFormat.format(CacheKey.content_subscribe_record, contentId, contentType);
            Set<Object> set = redisUtils.sGet(contentSubscribeKey);
            if (!ObjectUtils.isEmpty(set)) {
                JsonArray memberIds = new JsonArray();
                set.forEach(s -> {
                    memberIds.add(s.toString());
                });
                memberIds.forEach(m -> {
                    MemberVo memberVo = memberBiz.info(Integer.valueOf(m.toString().replaceAll("\"", "")));
                    if (!ObjectUtils.isEmpty(memberVo)) {
                        tokenList.add(memberVo.getPushToken());
                    }
                });
            }
        }


        //推送内容
        JsonObject pushConf = GsonUtils.fromJson(cacheBiz.getSystemDict(Constants.tencent_cloud_push_conf), JsonObject.class);
        String title = pushConf.get("title").getAsString();
        String contentFormat = pushConf.get("content").getAsString();
        String contentInfo = "";
        if (ColumnEnum.activity.getCode().equals(contentType)) {
            ActivityVo activityVo = activityBiz.getById(Integer.valueOf(content));
            if (ObjectUtils.isEmpty(activityVo) || activityVo.getState() == 0) {
                return;
            }
            contentInfo = activityVo.getTitle();
        }
        if (ColumnEnum.live.getCode().equals(contentType)) {
            LiveVo liveVo = liveBiz.getById(Integer.valueOf(content));
            if (ObjectUtils.isEmpty(liveVo) || liveVo.getState() == 0) {
                return;
            }
            contentInfo = liveVo.getTitle();
        }
        if (ColumnEnum.tv.getCode().equals(contentType)) {
            JsonObject schedule = GsonUtils.fromJson(content, JsonObject.class);
            contentInfo = schedule.get("title").getAsString();
            String channelId = schedule.get("channelId").getAsString();
            LiveVo liveVo = liveBiz.getByChannelId(channelId);
            if (!ObjectUtils.isEmpty(liveVo)) {
                contentId = liveVo.getLiveId().toString();
            }
        }

        contentInfo = MessageFormat.format(contentFormat, contentInfo);

        //推送渠道
        JsonObject body = new JsonObject();
        if (Channel.Android.getCode().equals(channel)) {
            body = buildAndroidBody(TpnsAudienceType.getValue(audience_type), tokenList, title, contentInfo, contentType, contentId);
        }
        if (Channel.IOS.getCode().equals(channel)) {
            body = buildIosBody(TpnsAudienceType.getValue(audience_type), tokenList, title, contentInfo, contentType, contentId);
        }
        //完成推送
        push(channel, body);
    }

    public JsonObject buildAndroidBody(String audience_type, JsonArray tokenList, String title, String contentInfo, Integer contentType, String content) {
        JsonObject body = new JsonObject();
        body.addProperty("audience_type", audience_type);
        body.addProperty("message_type", "notify");
        if ("token_list".equals(audience_type)) {
            body.add("token_list", tokenList);
        }
        JsonObject message = new JsonObject();
        message.addProperty("title", title);
        message.addProperty("content", contentInfo);
        JsonObject android = new JsonObject();
        JsonObject action = new JsonObject();
        action.addProperty("action_type", 3);
        String intent = "";
        if (TpnsContentType.activity.getCode().equals(contentType)) {
            intent = "app://hntv/ActivityUI?activity_id=" + content;
        }
        if (TpnsContentType.tv.getCode().equals(contentType) || TpnsContentType.live.getCode().equals(contentType)) {
            intent = "app://hntv/VodDetail?liveId=" + content;
        }
        if (TpnsContentType.h5.getCode().equals(contentType)) {
            intent = "app://hntv/WebUI?url=" + content;
        }
        action.addProperty("intent", intent);
        android.add("action", action);
        message.add("android", android);
        body.add("message", message);
        return body;
    }

    public JsonObject buildIosBody(String audience_type, JsonArray tokenList, String title, String contentInfo, Integer contentType, String content) {
        JsonObject body = new JsonObject();
        body.addProperty("audience_type", audience_type);
        body.addProperty("message_type", "notify");
        body.addProperty("environment", "product");
        if ("token_list".equals(audience_type)) {
            body.add("token_list", tokenList);
        }
        JsonObject message = new JsonObject();
        message.addProperty("title", title);
        message.addProperty("content", contentInfo);
        JsonObject ios = new JsonObject();
        JsonObject aps = new JsonObject();
        String url = "";
        if (TpnsContentType.activity.getCode().equals(contentType)) {
            url = "com.chinaotttv.snailapp://open?type=activity&id=" + content;
        }
        if (TpnsContentType.tv.getCode().equals(contentType) || TpnsContentType.live.getCode().equals(contentType)) {
            url = "com.chinaotttv.snailapp://open?type=live&id=" + content;
        }
        if (TpnsContentType.h5.getCode().equals(contentType)) {
            url = "com.chinaotttv.snailapp://open?type=h5&id=" + content;
        }
        JsonObject custom_content = new JsonObject();
        custom_content.addProperty("url", url);
        aps.addProperty("mutable-content", 1);
        ios.addProperty("custom_content", custom_content.toString());
        ios.add("aps", aps);
        message.add("ios", ios);
        body.add("message", message);
        return body;
    }

    public String sign(String original, String secretKey) {
        String sign = "";
        try {
            Mac mac;
            mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA256"));
            byte[] signatureBytes = mac.doFinal(original.getBytes("UTF-8"));
            String hexStr = Hex.encodeHexString(signatureBytes);
            sign = Base64.encodeBase64String(hexStr.getBytes());
        } catch (Exception e) {
            log.error("推送签名错误:{}", e);
        }
        return sign;
    }

    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
        JsonObject body = new JsonObject();
        body.addProperty("audience_type", "token_list");
        body.addProperty("message_type", "notify");
        //body.addProperty("environment", "product");
        //body.addProperty("message_type", "message");

        JsonArray array = new JsonArray();
        array.add("03140c7f41dbaa70a08f7a573c5f9a334627");
        body.add("token_list", array);
//
        JsonObject message = new JsonObject();
        message.addProperty("title", "系统消息");
        message.addProperty("content", "您预约的秘境之眼(194)即将开始，点击查看");

        JsonObject android = new JsonObject();
        JsonObject action = new JsonObject();
        action.addProperty("action_type", 3);
        //action.addProperty("intent", "app://hntv/ActivityUI?activity_id=18");
        action.addProperty("intent", "app://hntv/VodDetail?liveId=1936");
        //action.addProperty("activity", "app://hntv/ActivityUI?activity_id=18");
        android.add("action", action);
        message.add("android", android);
//
//		JsonObject ios = new JsonObject();
//		JsonObject aps = new JsonObject();
//		JsonObject alert = new JsonObject();
//		alert.addProperty("subtitle", "my subtitle");
//		aps.add("alert", alert);
        //aps.addProperty("mutable-content", 1);

//		JsonObject custom_content = new JsonObject();
//		custom_content.addProperty("url", "com.chinaotttv.snailtv://open?type=h5&id=http://baidu.com");
//		ios.addProperty("custom_content", custom_content.toString());
//		ios.add("aps", aps);
//
//		message.add("ios", ios);

        body.add("message", message);

        String timeStamp = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")) + "";
        String original = "1595297389" + "1500006096" + body.toString();
//		String appSecret = "4ccf574514a4c1db39154454d639a733";
        //String original = timeStamp + "1500006096" + body.toString();
        String appSecret = "4ccf574514a4c1db39154454d639a733";
        Mac mac;
        mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(appSecret.getBytes("UTF-8"), "HmacSHA256"));
        byte[] signatureBytes = mac.doFinal(original.getBytes("UTF-8"));
        String hexStr = Hex.encodeHexString(signatureBytes);
        String signature = Base64.encodeBase64String(hexStr.getBytes());
    }
}
